注:此方法所有计算都是手工的,一步一步来。 “小费问题”通常用来说明模糊逻辑原理从一组紧凑、直观的专家规则生成复杂行为的能力。
在决定就餐时给多少小费时,有很多变量。考虑其中的两个:
输出变量只是小费的数量,以百分比表示:
为了便于讨论,我们假设输入变量和输出变量都需要“高”、“中”和“低”隶属度函数。这些在scikit-fuzzy中定义如下
现在,为了使这些三角形有用,我们定义输入变量和输出变量之间的模糊关系。对于我们的例子,考虑三条简单的规则:
大多数人会同意这些规则,但这些规则是模糊的。将不精确的规则映射为定义的、可操作的提示是一项挑战。这是模糊逻辑擅长的一类任务。
在以下情况下:
已知单个隶属函数之后需要合并它们。这通常使用最大操作符来完成。这一步也被称为聚合。
最后,为了得到一个真实的世界答案,我们返回清晰值。我们这个例子中使用质心法。 结果是20.2%的小费。
模糊系统是允许复杂的、直观的行为基于一个开销最小的规则稀疏系统。注意,我们的隶属度函数是粗糙的,仅在整数处定义,但fuzzy .interp_membership允许有效的分辨率随需求而增加。该系统可以对输入的任意小变化作出响应,处理负担最小。
import numpy as np
import skfuzzy as fuzz
import matplotlib.pyplot as plt
%matplotlib inline
from skfuzzy import control as ctrl
# New Antecedent/Consequent objects hold universe variables and membership
# functions
quality = ctrl.Antecedent(np.arange(0, 11, 1), 'quality')
service = ctrl.Antecedent(np.arange(0, 11, 1), 'service')
tip = ctrl.Consequent(np.arange(0, 26, 1), 'tip')
# Auto-membership function population is possible with .automf(3, 5, or 7)
quality.automf(3)
service.automf(3)
# Custom membership functions can be built interactively with a familiar,
# Pythonic API
tip['low'] = fuzz.trimf(tip.universe, [0, 0, 13])
tip['medium'] = fuzz.trimf(tip.universe, [0, 13, 25])
tip['high'] = fuzz.trimf(tip.universe, [13, 25, 25])
To help understand what the membership looks like, use the view
methods.
These return the matplotlib Figure
and Axis
objects. They are persistent
as written in Jupyter notebooks; other environments may require a plt.show()
command after each .view()
.
# You can see how these look with .view()
quality['average'].view()
D:\software_install\anaconda\lib\site-packages\skfuzzy\control\term.py:74: UserWarning: Matplotlib is currently using module://matplotlib_inline.backend_inline, which is a non-GUI backend, so cannot show the figure. fig.show()
service.view()
D:\software_install\anaconda\lib\site-packages\skfuzzy\control\fuzzyvariable.py:122: UserWarning: Matplotlib is currently using module://matplotlib_inline.backend_inline, which is a non-GUI backend, so cannot show the figure. fig.show()
tip.view()
D:\software_install\anaconda\lib\site-packages\skfuzzy\control\fuzzyvariable.py:122: UserWarning: Matplotlib is currently using module://matplotlib_inline.backend_inline, which is a non-GUI backend, so cannot show the figure. fig.show()
Fuzzy rules
Now, to make these triangles useful, we define the fuzzy relationship between input and output variables. For the purposes of our example, consider three simple rules:
rule1 = ctrl.Rule(quality['poor'] | service['poor'], tip['low'])
rule2 = ctrl.Rule(service['average'], tip['medium'])
rule3 = ctrl.Rule(service['good'] | quality['good'], tip['high'])
rule1.view()
(<Figure size 432x288 with 1 Axes>, <AxesSubplot:>)
Control System Creation and Simulation
Now that we have our rules defined, we can simply create a control system via:
tipping_ctrl = ctrl.ControlSystem([rule1, rule2, rule3])
In order to simulate this control system, we will create a
ControlSystemSimulation
. Think of this object representing our controller
applied to a specific set of circumstances. For tipping, this might be tipping
Sharon at the local brew-pub. We would create another
ControlSystemSimulation
when we're trying to apply our tipping_ctrl
for Travis at the cafe because the inputs would be different.
tipping = ctrl.ControlSystemSimulation(tipping_ctrl)
We can now simulate our control system by simply specifying the inputsand calling the compute
method. Suppose we rated the quality 6.5 out of 10 and the service 9.8 of 10.
# Pass inputs to the ControlSystem using Antecedent labels with Pythonic API
# Note: if you like passing many inputs all at once, use .inputs(dict_of_data)
tipping.input['quality'] = 6.5
tipping.input['service'] = 9.8
# Crunch the numbers
tipping.compute()
Once computed, we can view the result as well as visualize it.
print(tipping.output['tip'])
tip.view(sim=tipping)
19.847607361963192
D:\software_install\anaconda\lib\site-packages\skfuzzy\control\fuzzyvariable.py:122: UserWarning: Matplotlib is currently using module://matplotlib_inline.backend_inline, which is a non-GUI backend, so cannot show the figure. fig.show()
The resulting suggested tip is 19.84%.
Final thoughts
The power of fuzzy systems is allowing complicated, intuitive behavior based
on a sparse system of rules with minimal overhead. Note our membership
function universes were coarse, only defined at the integers, but
fuzz.interp_membership
allowed the effective resolution to increase on
demand. This system can respond to arbitrarily small changes in inputs,
and the processing burden is minimal.